﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace _2022Learning._04.Delegate
{
    /// <summary>
    /// 观察者模式：属于行为性设计模式的一种，关注对象与行为的分离
    /// 解决的问题：一个对象发生一个事情只后，会触发一些列的其他对象的动作，但是又不希望对象之间紧密的依赖
    /// </summary>
    public class ObserverPattern
    {
    }

    /// <summary>
    /// 发布者：水壶
    /// 水壶烧水，温度达到一定的温度之后，发送水已烧开的信息（消息），并且触发灯光报警（订阅者）和响铃（订阅者）
    /// </summary>
    public class Spoon
    {
        /// <summary>
        /// 温度,温度默认40度
        /// </summary>
        public int temp { get; set; } = 40;

        /// <summary>
        /// 定义水烧开事件
        /// 事件其实是一种特殊的委托，但是有一点区别是，事件只能在定义类中触发
        /// </summary>
        public event Action<int> WaterFireEvent;

        /// <summary>
        /// 绑定处理事件，订阅者将行为绑定到发布者，发布者统一触发
        /// A对象通过委托的方式将行为注册到B对象，这样就相当于B对象直接触发了A对象的行为
        /// </summary>
        /// <param name="action"></param>
        public void SubsAction(Action<int> action)
        {
            WaterFireEvent += action;
        }

        public void Boilwater()
        {
            Console.WriteLine("开始烧水啦！");
            while(this.temp < 100)
            {
                this.temp += 5;
                Console.WriteLine($"持续烧水中...,当前水温度{this.temp}");
                Thread.Sleep(2000);
            }
            WaterFireEvent.Invoke(this.temp);

        }
    }

    /// <summary>
    /// 订阅者响应类
    /// </summary>
    public abstract class SubsActions
    {
        public abstract void doAction(int temp);
    }

    /// <summary>
    /// 灯光 
    /// </summary>
    public class Light : SubsActions
    {
        public override void doAction(int temp)
        {
            Console.WriteLine($"温度已达到{temp}摄氏度，红灯亮了！");
        }
    }

    /// <summary>
    /// 响铃
    /// </summary>
    public class Bell : SubsActions
    {
        public override void doAction(int temp)
        {
            Console.WriteLine($"温度已达到{temp}摄氏度，响铃啦！");
        }
    }
}
